from fields import *

CATEGORY_LOW = "Low"
CATEGORY_MEDIUM = "Medium"
CATEGORY_HIGH = "High"
CATEGORY_FIXED = "Fixed"

class Template(list):
    
    def __init__(self,id,name,klass=CATEGORY_LOW,trusted=False,zerocoded=False):
        """initialize a packet template"""
        list.__init__(self)
        self.name = name
        self.klass = klass
        self.trusted = trusted
        self.zerocoded = zerocoded
        self._id = id

        self._blocks=[]
        self._blockmap={}

    def getId(self):
        """return the packet id"""
        return self._id

    def append(self,block):
        """add a block"""
        list.append(self,block)
        self._blockmap[block.name]=block

    addBlock = append

    def __len__(self):
        """compute length"""
        l=0
        for block in self: l+=len(block)
        return l

    def get(self,id,default=None):
        """return block with the given id"""
        return self._blockmap.get(id,default)


class Block(list):
    
    def __init__(self,name):
        """initialize a data block"""
        list.__init__(self)
        self.name = name
        self._fieldmap={}

    def append(self,field):
        """add a field"""
        list.append(self,field)
        self._fieldmap[field.name]=field

    addField = append

    def __len__(self):
        """compute length"""
        l=0
        for field in self:
            l+=len(field)
        return l



class MultipleBlock(Block):
    """a block of type multiple"""

    def __init__(self,name,multiplier):
        """initialize multiple block"""
        Block.__init__(self,name)
        self.multiplier = multiplier

def testme():
    """

    First we create some template object and we use the CompleteAgentMovement template as example:
    >>> tmpl = Template(1,"CompleteAgentMovement","Low",False,"Unencoded") # TODO: make Unencoded a constant or just a BOOL

    Then we create a block with the name "AgentData". The name is more for internal use and not transfered.
    >>> agentdata = Block("AgentData")

    Now we can fill the blocks fields:
    >>> agent_uuid = "35353fa3-8303-4d1b-aa08-f54416c8c921"
    >>> session_uuid = "35353fa3-8303-4d1b-aa08-f54416c8c921"
    >>> agentdata.append(LLUUIDField("AgentID"))
    >>> agentdata.append(LLUUIDField("SessionID"))
    >>> agentdata.append(U32Field("CircuitCode"))

    And then we add this block to the list of blocks for that template (TODO: check of bad blocks)
    >>> tmpl.append(agentdata)

    check the length of the block
    >>> len(agentdata)
    36

    Now that we have the template defined we can read it again, e.g. we have one block
    >>> len(tmpl)
    36

    Let's retrieve this block
    >>> b = tmpl[0]
    >>> b.name
    'AgentData'

    Let's use another method for retrieving

    >>> b = tmpl.get("AgentData")
    >>> b.name
    'AgentData'

    In case of multiple blocks we have a different result (TODO!)

    Now with the template let's create a message

    >>> from message import Message
    >>> msg = Message(tmpl)

    And add the block vars:

    >>> msg.AgentData.AgentID.value=agent_uuid
    >>> msg.AgentData.SessionID.value=session_uuid
    >>> msg.AgentData.CircuitCode.value=56212

    Now convert it to a hex representation

    >>> from binascii import hexlify
    >>> hexlify(msg.toBytes())
    '35353fa383034d1baa08f54416c8c92135353fa383034d1baa08f54416c8c9210000db94'







    """


def _test():
    """test this module"""
    import doctest
    doctest.testmod()

if __name__=="__main__":
    _test()
